package org.openfdtd.core3d;

import java.awt.Color;
import javax.media.j3d.LineArray;
import javax.media.j3d.Shape3D;
import javax.vecmath.Color3f;

/**
 *
 * @author Dorian C. Langbeck
 */
//TODO: Extender SceneComponent posteriormente
public class ViewGrid extends SceneComponent {
    public static final Color3f COLOR_X = new Color3f(Color.RED);
    public static final Color3f COLOR_Y = new Color3f(Color.GREEN);
    public static final Color3f COLOR_Z = new Color3f(Color.BLUE);
    public static final Color3f COLOR_GRID = new Color3f(0.7f, 0.7f, 0.7f);
    public static final Color3f COLOR_SUBGRID = new Color3f(0.85f, 0.85f, 0.85f);

    public ViewGrid(double gridSize, double range) {
        super(false);
        setPickable(false);
        LineArray laCenter = new LineArray(6, LineArray.COORDINATES | LineArray.COLOR_3);
        laCenter.setCoordinates(0, new double[] {
            range, 0, 0,
            -range, 0, 0,
            0, range, 0,
            0, -range, 0,
            0, 0, range,
            0, 0, -range
        });

        laCenter.setColors(0, new Color3f[] {
            ViewGrid.COLOR_X,
            ViewGrid.COLOR_X,
            ViewGrid.COLOR_Y,
            ViewGrid.COLOR_Y,
            ViewGrid.COLOR_Z,
            ViewGrid.COLOR_Z
        });

        //Adiciona as linhas dos eixos
        Shape3D shape = new Shape3D(laCenter);

        int ng = (int) (range / gridSize);
        int total = ng * 4 + 4;
        LineArray laGrigX = new LineArray(total, LineArray.COORDINATES | LineArray.COLOR_3);
        LineArray laGrigY = new LineArray(total, LineArray.COORDINATES | LineArray.COLOR_3);

        int sgTotal = total * 20;
        LineArray laSGrigX = new LineArray(sgTotal, LineArray.COORDINATES | LineArray.COLOR_3);
        LineArray laSGrigY = new LineArray(sgTotal, LineArray.COORDINATES | LineArray.COLOR_3);
        double sgSize = gridSize / 10;

        Color3f[] cg = new Color3f[] {ViewGrid.COLOR_GRID, ViewGrid.COLOR_GRID};
        Color3f[] csg = new Color3f[] {ViewGrid.COLOR_SUBGRID, ViewGrid.COLOR_SUBGRID};
        int isp = 0, isn = ng << 1 + 4;
        for (int i = 1; i <= ng; i++) {
            int ip = i << 1, in = ng + i << 1;
            double pos = i * gridSize;

            laGrigX.setCoordinates(ip, new double[] {
                range, pos, 0,
                -range, pos, 0
            });

            laGrigX.setCoordinates(in, new double[] {
                range, -pos, 0,
                -range, -pos, 0
            });

            laGrigY.setCoordinates(ip, new double[] {
                pos, range, 0,
                pos, -range, 0
            });

            laGrigY.setCoordinates(in, new double[] {
                -pos, range, 0,
                -pos, -range, 0
            });

            laGrigX.setColors(ip, cg);
            laGrigX.setColors(in, cg);
            laGrigY.setColors(ip, cg);
            laGrigY.setColors(in, cg);

            
            for (int sg = 1; sg < 10; sg++, isp += 2, isn += 2) {
                double subPos = pos - sg * sgSize;

                laSGrigX.setCoordinates(isp, new double[] {
                    range, subPos, 0,
                    -range, subPos, 0
                });

                laSGrigX.setCoordinates(isn, new double[] {
                    range, -subPos, 0,
                    -range, -subPos, 0
                });

                laSGrigY.setCoordinates(isp, new double[] {
                    subPos, range, 0,
                    subPos, -range, 0
                });

                laSGrigY.setCoordinates(isn, new double[] {
                    -subPos, range, 0,
                    -subPos, -range, 0
                });

                laSGrigX.setColors(isp, csg);
                laSGrigX.setColors(isn, csg);
                laSGrigY.setColors(isp, csg);
                laSGrigY.setColors(isn, csg);
            }
        }

        //Adiciona as grades e subgrades
        shape.addGeometry(laGrigX);
        shape.addGeometry(laGrigY);
        shape.addGeometry(laSGrigX);
        shape.addGeometry(laSGrigY);

        addChild(shape);
    }
}
